#!/bin/sh

set -e

sitename="puppetmaster"
apache2_version="$(dpkg-query --showformat='${Version}\n' --show apache2)"

# The debian provided a2* utils in Apache 2.4 uses "site name" as
# argument, while the version in Apache 2.2 uses "file name".
#
# For added fun, the Apache 2.4 version requires files to have a
# ".conf" suffix, but this must be stripped when using it as argument
# for the a2* utilities.
#
# This will end in tears…
# Can be removed when we only support apache >= 2.4
apache2_puppetmaster_sitename() {
    if dpkg --compare-versions "$apache2_version" gt "2.4~"; then
        echo "${sitename}.conf"
    else
        echo "${sitename}"
    fi
}

# Can be removed when we only support apache >= 2.4
restart_apache2() {
    if [ -x "/etc/init.d/apache2" ]; then
        # Seems that a restart is needed. reload breaks ssl apparently.
        if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then
            invoke-rc.d apache2 restart || exit $?
        else
            /etc/init.d/apache2 restart || exit $?
        fi
    fi
}

# We may need to update the passenger directives in the apache vhost because
# RailsAutoDetect and RackAutoDetect were removed in passenger 4.0.0
#       see http://www.modrails.com/documentation/Users%20guide%20Apache.html#_railsautodetect_rackautodetect_and_wsgiautodetect
update_vhost_for_passenger4() {
    # Get passenger version from dpkg.
    # This will end in tears…
    passenger_version="$(dpkg-query --showformat='${Version}\n' --show libapache2-mod-passenger)"
    if dpkg --compare-versions "$passenger_version" gt "4.0~"; then
        sed -r -i \
            -e "/RailsAutoDetect/d" \
            -e "/RackAutoDetect/d" \
            $tempfile
    fi
}

# In Apache 2.2, if either the SSLCARevocationFile or SSLCARevocationPath
# directives were specified then the specified file(s) would be checked when
# establishing an SSL connection. Apache 2.4+ the SSLCARevocationCheck directive
# was added to control how CRLs were checked when verifying a connection and had
# a default value of none.  This means that Apache defaults to ignoring CRLs even
# if paths are specified to CRL files.
#
# This function automatically uncomments the SSLCARevocationCheck directive when
# the currently installed version of Apache is 2.4.
update_vhost_for_apache24() {
    if dpkg --compare-versions "$apache2_version" gt "2.4~"; then
        sed -r -i \
            -e "/# SSLCARevocationCheck/s/# //" \
        $tempfile
    fi
}

# Update an existing vhost definition with the SSLCARevocationCheck directive
# on Apache 2.4+. This scans an existing vhost file for the SSLCARevocationCheck
# directive and adds it to the file after the SSLCARevocationFile directive.
#
# See https://tickets.puppetlabs.com/browse/PUP-2533 for more information.
update_vhost_for_apache24_upgrade() {
    APACHE2_SITE_FILE="/etc/apache2/sites-available/$(apache2_puppetmaster_sitename)"

    if dpkg --compare-versions "$apache2_version" gt "2.4~"; then
        if ! grep -q "^[[:space:]]*SSLCARevocationCheck" $APACHE2_SITE_FILE ; then
            tempfile=$(mktemp)
            sed -r \
                -e "/SSLCARevocationFile/a\\        SSLCARevocationCheck chain" \
                $APACHE2_SITE_FILE > $tempfile
            mv $tempfile $APACHE2_SITE_FILE
        fi
    fi
}


create_initial_puppetmaster_vhost() {
    # Check that puppet master --configprint works properly
    # If it doesn't the following steps to update the vhost will produce a very unhelpful and broken vhost
    if [ $(puppet master --configprint all 2>&1 | grep "Could not parse" | wc -l) != "0" ]; then
        echo "Puppet config print not working properly, exiting"
        exit 1
    fi

    # Initialize puppetmaster CA and generate the master certificate
    # only if the host doesn't already have any puppet ssl certificate.
    # The ssl key and cert need to be available (eg generated) before
    # apache2 is configured and started since apache2 ssl configuration
    # uses the puppetmaster ssl files.
    if [ ! -e "$(puppet master --configprint hostcert)" ]; then
        puppet cert generate $(puppet master --configprint certname)
    fi

    # Setup apache2 configuration files
    APACHE2_SITE_FILE="/etc/apache2/sites-available/$(apache2_puppetmaster_sitename)"
    if  [ ! -e "${APACHE2_SITE_FILE}" ]; then
        tempfile=$(mktemp)
        sed -r \
            -e "s|(SSLCertificateFile\s+).+$|\1$(puppet master --configprint hostcert)|" \
            -e "s|(SSLCertificateKeyFile\s+).+$|\1$(puppet master --configprint hostprivkey)|" \
            -e "s|(SSLCACertificateFile\s+).+$|\1$(puppet master --configprint localcacert)|" \
            -e "s|(SSLCertificateChainFile\s+).+$|\1$(puppet master --configprint localcacert)|" \
            -e "s|(SSLCARevocationFile\s+).+$|\1$(puppet master --configprint cacrl)|" \
            -e "s|DocumentRoot /etc/puppet/rack/public|DocumentRoot /usr/share/puppet/rack/puppetmasterd/public|" \
            -e "s|<Directory /etc/puppet/rack/>|<Directory /usr/share/puppet/rack/puppetmasterd/>|" \
            /usr/share/puppetmaster-passenger/apache2.site.conf.tmpl > $tempfile
        update_vhost_for_passenger4
        update_vhost_for_apache24
        mv $tempfile "${APACHE2_SITE_FILE}"
    fi

    # Enable needed modules
    a2enmod ssl
    a2enmod headers
    a2ensite ${sitename}
    restart_apache2
}

update_existing_puppetmaster_vhost() {
    if dpkg --compare-versions "${1}" lt "3.6.2~"; then
        update_vhost_for_apache24_upgrade
    fi
}

if [ "$1" = "configure" ]; then

    # Change the owner of the rack config.ru to be the puppet user
    # because passenger will suid to that user, see #577366
    if ! dpkg-statoverride --list /usr/share/puppet/rack/puppetmasterd/config.ru >/dev/null 2>&1
    then
        dpkg-statoverride --update --add puppet puppet 0644 /usr/share/puppet/rack/puppetmasterd/config.ru
    fi

    # Setup puppetmaster passenger vhost
    if [ "$2" = "" ]; then
        create_initial_puppetmaster_vhost
    else
        update_existing_puppetmaster_vhost $2
    fi

    # Fix CRL file on upgrade to use the CA crl file instead of the host crl.
    if dpkg --compare-versions "$2" lt-nl "2.6.1-1"; then
        if [ -e /etc/apache2/sites-available/puppetmaster ]; then
            sed -r -i 's|SSLCARevocationFile[[:space:]]+/var/lib/puppet/ssl/crl.pem$|SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem|' /etc/apache2/sites-available/puppetmaster
            restart_apache2
        fi
    fi
fi

#DEBHELPER#
